home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / linuxdoc-sgml-1.1 / sgmls-1.1 / exclude.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  2.3 KB  |  122 lines

  1. /* exclude.c -
  2.    Exclusion checking.
  3.  
  4.      Written by James Clark (jjc@jclark.com).
  5. */
  6.  
  7. #include "sgmlincl.h"
  8.  
  9. static int excktok P((struct thdr *, int, int *));
  10. static int exmark P((int));
  11.  
  12. /* Check that the current exclusions are legal for the content model
  13. of the current element. */
  14.  
  15. VOID exclude()
  16. {
  17.      struct thdr *mod = tags[ts].tetd->etdmod;
  18.  
  19.      if ((mod->ttype & MKEYWORD) == 0 && exmark(1)) {
  20.       int excl;
  21.       
  22.       excktok(mod + 1, 0, &excl);
  23.       exmark(0);
  24.      }
  25. }
  26.  
  27. /* Set the mark field of all current exclusions to val.  Return 1 if
  28. there are some current exclusions. */
  29.  
  30. static
  31. int exmark(val)
  32. int val;
  33. {
  34.      int i;
  35.      int gotone = 0;
  36.  
  37.      for (i = ts; i > 0; --i) {
  38.       struct etd **p = tags[i].tetd->etdmex;
  39.       if (p) {
  40.            for (; *p; p++)
  41.             (*p)->mark = val;
  42.            gotone = 1;
  43.       }
  44.      }
  45.      return gotone;
  46. }
  47.  
  48. /* Check exclusions for this token.  Return size of token. */
  49.  
  50. static
  51. int excktok(t, orgrp, excl)
  52. struct thdr *t;
  53. int orgrp;            /* 1 if token is member of or group */
  54. int *excl;            /* Set to 1 if token is excluded. */
  55. {
  56.      int size;
  57.      struct thdr *tem;
  58.      int tnum;
  59.      int optional = 0;
  60.      int hadopt, hadreq;
  61.      
  62.      *excl = 0;
  63.  
  64.      switch (t->ttype & TTMASK) {
  65.      case TTETD:
  66.       if (t->tu.thetd->mark) {
  67.            if (orgrp || (t->ttype & TOPT))
  68.             *excl = 1;
  69.            else
  70.             sgmlerr(217, &pcbstag, t->tu.thetd->etdgi + 1,
  71.                 tags[ts].tetd->etdgi + 1);
  72.       }
  73.       /* fall through */
  74.      case TTCHARS:
  75.       size = 1;
  76.       break;
  77.      case TTOR:
  78.      case TTAND:
  79.      case TTSEQ:
  80.       tem = t + 1;
  81.       hadopt = 0;
  82.       hadreq = 0;
  83.       for (tnum = t->tu.tnum; tnum > 0; --tnum) {
  84.            int ex;
  85.            int n = excktok(tem, (t->ttype & TTMASK) == TTOR, &ex);
  86.            if (!ex) {
  87.             if (tem->ttype & TOPT)
  88.              hadopt = 1;
  89.             else
  90.              hadreq = 1;
  91.            }
  92.            tem += n;
  93.       }
  94.       size = tem - t;
  95.       if ((t->ttype & TTMASK) == TTOR)
  96.            optional = hadreq ? hadopt : 1;
  97.       else
  98.            optional = !hadreq;
  99.       break;
  100.      default:
  101.       abort();
  102.      }
  103.      
  104.      /* Was required, but exclusions have made it optional.
  105.        eg  <!element foo - - (a | b) -(a, b)> */
  106.  
  107.      if (optional && !(t->ttype & TOPT))
  108.       sgmlerr(216, &pcbstag, tags[ts].tetd->etdgi + 1, (UNCH *)0);
  109.  
  110.      return size;
  111. }
  112.  
  113. /*
  114. Local Variables:
  115. c-indent-level: 5
  116. c-continued-statement-offset: 5
  117. c-brace-offset: -5
  118. c-argdecl-indent: 0
  119. c-label-offset: -5
  120. End:
  121. */
  122.